﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;

namespace System
{
    [DataContract, Serializable]
    [DebuggerDisplay("Success:{Success}, StatusCode:{StatusCode}, Message:{Message}")]
    public class Result
    {
        public static string SuccessMessage = "操作成功！";
        public static string FailedMessage = "操作失败！";

        #region fields
        private bool _success;
        private int _statusCode;
        private string _message;
        #endregion

        #region Constructors
        public Result()
        {
            _success = false;
            _statusCode = 500;
            _message = FailedMessage;
        }
        public Result(bool success)
        {
            _success = success;
            _statusCode = success ? 200 : 500;
            _message = success ? SuccessMessage : FailedMessage;
        }
        public Result(string message)
        {
            _success = false;
            _statusCode = 500;
            _message = message;
        }
        public Result(int statusCode)
        {
            _success = false;
            _statusCode = statusCode;
            _message = FailedMessage;
        }
        public Result(bool success, string message)
        {
            _success = success;
            _statusCode = success ? 200 : 500;
            _message = message;
        }
        public Result(bool success, int statusCode)
        {
            _success = success;
            _statusCode = statusCode;
            _message = success ? SuccessMessage : FailedMessage;
        }
        public Result(int statusCode, string message)
        {
            _success = false;
            _statusCode = statusCode;
            _message = message;
        }
        public Result(bool success, int statusCode, string message)
        {
            _success = success;
            _statusCode = statusCode;
            _message = message;
        }
        #endregion

        #region DataMember
        [DataMember]
        public bool Success
        {
            get { return _success; }
            set { _success = value; }
        }
        [DataMember]
        public int StatusCode
        {
            get { return _statusCode; }
            set { _statusCode = value; }
        }
        [DataMember]
        public string Message
        {
            get
            {
                if (_message == null) { return string.Empty; }
                return _message;
            }
            set
            {
                if (value == null) value = string.Empty;
                _message = value;
            }
        }
        public void Reset()
        {
            _success = false;
            _statusCode = _success ? 200 : 500;
            _message = string.Empty;
        }
        public bool StatusEquals(Result another)
        {
            return _success == another.Success && _statusCode == another.StatusCode;
        }
        public void CopyErrorFromOther<TResult>(TResult result) where TResult : Result
        {
            if (result != null)
            {
                StatusCode = result.StatusCode;
                Message = result.Message;
            }
        }
        #endregion
    
        #region 创建并返回一个成功的结果对象

        /*****************************************************************************************************
         * 
         *    主要是方便获取到一些特殊状态的结果对象
         * 
         ******************************************************************************************************/
        /// <summary>
        /// 创建并返回一个失败的结果对象，该对象复制另一个结果对象的错误信息
        /// </summary>
        /// <typeparam name="T">目标数据类型</typeparam>
        /// <param name="result">之前的结果对象</param>
        /// <returns>带默认泛型对象的失败结果类</returns>
        public static Result<T> CreateFailedResult<T>(Result result)
        {
            return new Result<T>()
            {
                StatusCode = result.StatusCode,
                Message = result.Message,
            };
        }

        /// <summary>
        /// 创建并返回一个失败的结果对象，该对象复制另一个结果对象的错误信息
        /// </summary>
        /// <typeparam name="T1">目标数据类型一</typeparam>
        /// <typeparam name="T2">目标数据类型二</typeparam>
        /// <param name="result">之前的结果对象</param>
        /// <returns>带默认泛型对象的失败结果类</returns>
        public static Result<T1, T2> CreateFailedResult<T1, T2>(Result result)
        {
            return new Result<T1, T2>()
            {
                StatusCode = result.StatusCode,
                Message = result.Message,
            };
        }


        /// <summary>
        /// 创建并返回一个失败的结果对象，该对象复制另一个结果对象的错误信息
        /// </summary>
        /// <typeparam name="T1">目标数据类型一</typeparam>
        /// <typeparam name="T2">目标数据类型二</typeparam>
        /// <typeparam name="T3">目标数据类型三</typeparam>
        /// <param name="result">之前的结果对象</param>
        /// <returns>带默认泛型对象的失败结果类</returns>
        public static Result<T1, T2, T3> CreateFailedResult<T1, T2, T3>(Result result)
        {
            return new Result<T1, T2, T3>()
            {
                StatusCode = result.StatusCode,
                Message = result.Message,
            };
        }


        /// <summary>
        /// 创建并返回一个失败的结果对象，该对象复制另一个结果对象的错误信息
        /// </summary>
        /// <typeparam name="T1">目标数据类型一</typeparam>
        /// <typeparam name="T2">目标数据类型二</typeparam>
        /// <typeparam name="T3">目标数据类型三</typeparam>
        /// <typeparam name="T4">目标数据类型四</typeparam>
        /// <param name="result">之前的结果对象</param>
        /// <returns>带默认泛型对象的失败结果类</returns>
        public static Result<T1, T2, T3, T4> CreateFailedResult<T1, T2, T3, T4>(Result result)
        {
            return new Result<T1, T2, T3, T4>()
            {
                StatusCode = result.StatusCode,
                Message = result.Message,
            };
        }


        /// <summary>
        /// 创建并返回一个失败的结果对象，该对象复制另一个结果对象的错误信息
        /// </summary>
        /// <typeparam name="T1">目标数据类型一</typeparam>
        /// <typeparam name="T2">目标数据类型二</typeparam>
        /// <typeparam name="T3">目标数据类型三</typeparam>
        /// <typeparam name="T4">目标数据类型四</typeparam>
        /// <typeparam name="T5">目标数据类型五</typeparam>
        /// <param name="result">之前的结果对象</param>
        /// <returns>带默认泛型对象的失败结果类</returns>
        public static Result<T1, T2, T3, T4, T5> CreateFailedResult<T1, T2, T3, T4, T5>(Result result)
        {
            return new Result<T1, T2, T3, T4, T5>()
            {
                StatusCode = result.StatusCode,
                Message = result.Message,
            };
        }

        /// <summary>
        /// 创建并返回一个成功的结果对象
        /// </summary>
        /// <returns>成功的结果对象</returns>
        public static Result CreateSuccessResult()
        {
            return new Result()
            {
                Success = true,
                StatusCode = 0,
                Message =SuccessMessage,
            };
        }

        /// <summary>
        /// 创建并返回一个成功的结果对象，并带有一个参数对象
        /// </summary>
        /// <typeparam name="T">参数类型</typeparam>
        /// <param name="value">类型的值对象</param>
        /// <returns>成功的结果对象</returns>
        public static Result<T> CreateSuccessResult<T>(T value)
        {
            return new Result<T>()
            {
                Success = true,
                StatusCode = 0,
                Message = SuccessMessage,
                Data = value
            };
        }


        /// <summary>
        /// 创建并返回一个成功的结果对象，并带有两个参数对象
        /// </summary>
        /// <typeparam name="T1">第一个参数类型</typeparam>
        /// <typeparam name="T2">第二个参数类型</typeparam>
        /// <param name="value1">类型一对象</param>
        /// <param name="value2">类型二对象</param>
        /// <returns>成的结果对象</returns>
        public static Result<T1, T2> CreateSuccessResult<T1, T2>(T1 value1, T2 value2)
        {
            return new Result<T1, T2>()
            {
                Success = true,
                StatusCode = 0,
                Message = SuccessMessage,
                Data1 = value1,
                Data2 = value2,
            };
        }


        /// <summary>
        /// 创建并返回一个成功的结果对象，并带有三个参数对象
        /// </summary>
        /// <typeparam name="T1">第一个参数类型</typeparam>
        /// <typeparam name="T2">第二个参数类型</typeparam>
        /// <typeparam name="T3">第三个参数类型</typeparam>
        /// <param name="value1">类型一对象</param>
        /// <param name="value2">类型二对象</param>
        /// <param name="value3">类型三对象</param>
        /// <returns>成的结果对象</returns>
        public static Result<T1, T2, T3> CreateSuccessResult<T1, T2, T3>(T1 value1, T2 value2, T3 value3)
        {
            return new Result<T1, T2, T3>()
            {
                Success = true,
                StatusCode = 0,
                Message = SuccessMessage,
                Data1 = value1,
                Data2 = value2,
                Data3 = value3,
            };
        }

        /// <summary>
        /// 创建并返回一个成功的结果对象，并带有四个参数对象
        /// </summary>
        /// <typeparam name="T1">第一个参数类型</typeparam>
        /// <typeparam name="T2">第二个参数类型</typeparam>
        /// <typeparam name="T3">第三个参数类型</typeparam>
        /// <typeparam name="T4">第四个参数类型</typeparam>
        /// <param name="value1">类型一对象</param>
        /// <param name="value2">类型二对象</param>
        /// <param name="value3">类型三对象</param>
        /// <param name="value4">类型四对象</param>
        /// <returns>成的结果对象</returns>
        public static Result<T1, T2, T3, T4> CreateSuccessResult<T1, T2, T3, T4>(T1 value1, T2 value2, T3 value3, T4 value4)
        {
            return new Result<T1, T2, T3, T4>()
            {
                Success = true,
                StatusCode = 0,
                Message = SuccessMessage,
                Data1 = value1,
                Data2 = value2,
                Data3 = value3,
                Data4 = value4,
            };
        }


        /// <summary>
        /// 创建并返回一个成功的结果对象，并带有五个参数对象
        /// </summary>
        /// <typeparam name="T1">第一个参数类型</typeparam>
        /// <typeparam name="T2">第二个参数类型</typeparam>
        /// <typeparam name="T3">第三个参数类型</typeparam>
        /// <typeparam name="T4">第四个参数类型</typeparam>
        /// <typeparam name="T5">第五个参数类型</typeparam>
        /// <param name="value1">类型一对象</param>
        /// <param name="value2">类型二对象</param>
        /// <param name="value3">类型三对象</param>
        /// <param name="value4">类型四对象</param>
        /// <param name="value5">类型五对象</param>
        /// <returns>成的结果对象</returns>
        public static Result<T1, T2, T3, T4, T5> CreateSuccessResult<T1, T2, T3, T4, T5>(T1 value1, T2 value2, T3 value3, T4 value4, T5 value5)
        {
            return new Result<T1, T2, T3, T4, T5>()
            {
                Success = true,
                StatusCode = 0,
                Message = SuccessMessage,
                Data1 = value1,
                Data2 = value2,
                Data3 = value3,
                Data4 = value4,
                Data5 = value5,
            };
        }
        #endregion

        public string ToMessageShowString()
        {
            return string.Format("错误代号:{0} " + Environment.NewLine + "文本描述:{1}", StatusCode, Message);
        }

        public override string ToString()
        {
            return string.Format("错误代号:{0} " + Environment.NewLine + "文本描述:{1}", StatusCode, Message);
        }

        #region implicit operators

        public static implicit operator Result(bool value)
        {
            return new Result(value);
        }

        public static implicit operator Result(int statusCode)
        {
            return new Result(statusCode);
        }

        public static implicit operator Result(Enum statusCode)
        {
            return new Result(Convert.ToInt32(statusCode));
        }

        public static implicit operator Result(string error)
        {
            return new Result(error);
        }

        public static implicit operator bool(Result res)
        {
            return res.Success;
        }
        #endregion

    }
    [DataContract, Serializable]
    [DebuggerDisplay("Success:{Success}, StatusCode:{StatusCode}, Message:{Message}")]
    public class Result<T> : Result
    {
        #region Constructors
        public Result(): base()
        {
          
        }
        public Result(bool success)
            : base(success)
        {

        }
        public Result(string message)
            : base(message)
        {

        }
        public Result(int statusCode)
            : base(statusCode)
        {

        }
        public Result(bool success, string message)
            : base(success, message)
        {

        }
        public Result(bool success, int statusCode)
            : base(success, statusCode)
        {

        }
        public Result(int statusCode, string message)
            : base(statusCode, message)
        {

        }
        public Result(bool success, int statusCode, string message)
            : base(success, statusCode, message)
        {

        }
        #endregion
        public T Data { get; set; }     
    }
    [DataContract, Serializable]
    [DebuggerDisplay("Success:{Success}, StatusCode:{StatusCode}, Message:{Message}")]
    public class Result<T1, T2> : Result
    {
        #region Constructors
        public Result()
            : base()
        {

        }
        public Result(bool success)
            : base(success)
        {

        }
        public Result(string message)
            : base(message)
        {

        }
        public Result(int statusCode)
            : base(statusCode)
        {

        }
        public Result(bool success, string message)
            : base(success, message)
        {

        }
        public Result(bool success, int statusCode)
            : base(success, statusCode)
        {

        }
        public Result(int statusCode, string message)
            : base(statusCode, message)
        {

        }
        public Result(bool success, int statusCode, string message)
            : base(success, statusCode, message)
        {

        }
        #endregion
        public T1 Data1 { get; set; }
        public T2 Data2 { get; set; }
    }
    [DataContract, Serializable]
    [DebuggerDisplay("Success:{Success}, StatusCode:{StatusCode}, Message:{Message}")]
    public class Result<T1, T2, T3> : Result
    {
        #region Constructors
        public Result()
            : base()
        {

        }
        public Result(bool success)
            : base(success)
        {

        }
        public Result(string message)
            : base(message)
        {

        }
        public Result(int statusCode)
            : base(statusCode)
        {

        }
        public Result(bool success, string message)
            : base(success, message)
        {

        }
        public Result(bool success, int statusCode)
            : base(success, statusCode)
        {

        }
        public Result(int statusCode, string message)
            : base(statusCode, message)
        {

        }
        public Result(bool success, int statusCode, string message)
            : base(success, statusCode, message)
        {

        }
        #endregion

        /// <summary>
        /// 用户自定义的泛型数据1
        /// </summary>
        public T1 Data1 { get; set; }

        /// <summary>
        /// 用户自定义的泛型数据2
        /// </summary>
        public T2 Data2 { get; set; }
        /// <summary>
        /// 用户自定义的泛型数据2
        /// </summary>
        public T3 Data3 { get; set; }
    }
    [DataContract, Serializable]
    [DebuggerDisplay("Success:{Success}, StatusCode:{StatusCode}, Message:{Message}")]
    public class Result<T1, T2, T3, T4> : Result
    {
        #region Constructors
        public Result()
            : base()
        {

        }
        public Result(bool success)
            : base(success)
        {

        }
        public Result(string message)
            : base(message)
        {

        }
        public Result(int statusCode)
            : base(statusCode)
        {

        }
        public Result(bool success, string message)
            : base(success, message)
        {

        }
        public Result(bool success, int statusCode)
            : base(success, statusCode)
        {

        }
        public Result(int statusCode, string message)
            : base(statusCode, message)
        {

        }
        public Result(bool success, int statusCode, string message)
            : base(success, statusCode, message)
        {

        }
        #endregion

        public T1 Data1 { get; set; }
        public T2 Data2 { get; set; }
        public T3 Data3 { get; set; }
        public T4 Data4 { get; set; }
    }
    [DataContract, Serializable]
    [DebuggerDisplay("Success:{Success}, StatusCode:{StatusCode}, Message:{Message}")]
    public class Result<T1, T2, T3, T4, T5> : Result
    {
        #region Constructors
        public Result()
            : base()
        {

        }
        public Result(bool success)
            : base(success)
        {

        }
        public Result(string message)
            : base(message)
        {

        }
        public Result(int statusCode)
            : base(statusCode)
        {

        }
        public Result(bool success, string message)
            : base(success, message)
        {

        }
        public Result(bool success, int statusCode)
            : base(success, statusCode)
        {

        }
        public Result(int statusCode, string message)
            : base(statusCode, message)
        {

        }
        public Result(bool success, int statusCode, string message)
            : base(success, statusCode, message)
        {

        }
        #endregion

        public T1 Data1 { get; set; }
        public T2 Data2 { get; set; }
        public T3 Data3 { get; set; }
        public T4 Data4 { get; set; }
        public T5 Data5 { get; set; }
    }
}
